package cn.dengta.webapp.trade.dao;

import java.util.Date;

import cn.dengta.common.model.TimeInterval;
import cn.dengta.common.web.Page;
import cn.dengta.webapp.base.dao.BaseDao;
import cn.dengta.webapp.base.util.MybatisUtil;
import cn.dengta.webapp.trade.dto.UserAgentDTO;
import cn.dengta.webapp.trade.entity.Agent;
import cn.dengta.webapp.trade.model.TradeType;
import cn.dengta.webapp.user.form.query.UserQuery;
import me.codeplayer.util.X;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.jdbc.SQL;

import static cn.dengta.webapp.base.entity.TimeBasedEntity.ADD_TIME;
import static cn.dengta.webapp.trade.entity.Agent.*;

public interface AgentDao extends BaseDao<Agent> {

	@Update("UPDATE dt_agent SET user_rate = #{userRate} WHERE id = #{id}")
	int updateUserRate(@Param("id") Long id, @Param("userRate") Integer userRate);

	@SelectProvider(type = AgentSQL.class, method = "findSecondPage")
	Page<UserAgentDTO> findSecondPage(Page<Agent> page, @Param("input") UserQuery query, @Param("interval") TimeInterval addTimeInterval, @Param("tradeTypes") TradeType... tradeTypes);

	@SelectProvider(type = AgentSQL.class, method = "findSecondPageV2")
	Page<UserAgentDTO> findSecondPageV2(Page<Agent> page, @Param("input") UserQuery query, @Param("interval") TimeInterval addTimeInterval, @Param("tradeTypes") TradeType... tradeTypes);

	class AgentSQL {

		public String findSecondPage(Page<Agent> page, @Param("input") UserQuery query, @Param("interval") TimeInterval addTimeInterval, @Param("tradeTypes") TradeType... tradeTypes) {
			final boolean hasTradeType = X.isValid(tradeTypes);
			SQL sql = new SQL().SELECT("at.*, e.agent_id agentId, e.id userId, e.avatar avatar, e.username userUsername,e.invite_user_id inviteUserId, e.phone userPhone,  e.email email, e.nickname userNickname, e.real_name userRealName, e.gender gender," +
					"e.`status` `userStatus`,"+
							" e.last_login_time lastLoginTime, e.last_active lastActive, e.agent_join_time agentJoinTime, e.add_time userAddTime " + (hasTradeType ? ", IFNULL(SUM(uiLog.trade_amount),0) totalTradeAmount" : ""))
					.FROM("dt_agent at")
					.INNER_JOIN("dt_user e ON e.id = at.user_id")
					.LEFT_OUTER_JOIN("dt_user u ON at.id = u.agent_id");
			if (query != null) {
				MybatisUtil.appendEqSql(sql, "at." + USER_ID, query.getUserId(), "#{input.userId}");
				MybatisUtil.appendEqSql(sql, "at." + PARENT_ID, query.getParentId(), "#{input.parentId}");
			}
			MybatisUtil.appendSqlInterval(sql, "at." + ADD_TIME, addTimeInterval, null);
			MybatisUtil.appendSqlInterval(sql, "at." + SIGN_EXPIRE_TIME, addTimeInterval, "signInterval");
			if (hasTradeType) {

				StringBuilder onAddTimeIntervalSQL = new StringBuilder();

				if (query != null) {
					X.use(query.getAddTimeInterval(), ti -> {
						Date begin = ti.getFinalBegin();
						if (begin != null) {
							onAddTimeIntervalSQL.append(" AND uiLog.add_time >= #{input.addTimeInterval.finalBegin}");
						}
						Date end = ti.getFinalEnd();
						if (end != null) {
							onAddTimeIntervalSQL.append(" AND uiLog.add_time <= #{input.addTimeInterval.finalEnd}");
						}
					});
				}
				sql.LEFT_OUTER_JOIN("tr_user_integral_log uiLog ON uiLog.user_id = u.id AND  uiLog.agent2_id = u.agent_id AND uiLog.handle_status >= 0 AND uiLog.add_time > u.agent_join_time AND " + MybatisUtil.inStrSql("uiLog.trade_type", tradeTypes) + onAddTimeIntervalSQL);

				sql.GROUP_BY("e.agent_id");
			}
			sql.GROUP_BY("at.id");
			sql.ORDER_BY(hasTradeType ? "SUM(uiLog.trade_amount) desc, at.id desc, at.status desc" : "at.id desc, at.status desc ");
			return sql.toString();
		}


		public String findSecondPageV2(Page<Agent> page, @Param("input") UserQuery query, @Param("interval") TimeInterval addTimeInterval, @Param("tradeTypes") TradeType... tradeTypes) {
			final boolean hasTradeType = X.isValid(tradeTypes);
			SQL sql = new SQL().SELECT("at.*, e.agent_id agentId, e.id userId, e.avatar avatar, e.username userUsername,e.invite_user_id inviteUserId, e.phone userPhone,  e.email email, e.nickname userNickname, e.real_name userRealName, e.gender gender," +
							"e.`status` `userStatus`,"+
							" e.last_login_time lastLoginTime, e.last_active lastActive, e.agent_join_time agentJoinTime, e.add_time userAddTime " + (hasTradeType ? ", IFNULL(SUM(uiLog.total_integral),0) totalTradeAmount" : ""))
					.FROM("dt_agent at")
					.INNER_JOIN("dt_user e ON e.id = at.user_id")
					.LEFT_OUTER_JOIN("dt_user u ON at.id = u.agent_id");
			if (query != null) {
				MybatisUtil.appendEqSql(sql, "at." + USER_ID, query.getUserId(), "#{input.userId}");
				MybatisUtil.appendEqSql(sql, "at." + PARENT_ID, query.getParentId(), "#{input.parentId}");
			}
			MybatisUtil.appendSqlInterval(sql, "at." + ADD_TIME, addTimeInterval, null);
			MybatisUtil.appendSqlInterval(sql, "at." + SIGN_EXPIRE_TIME, addTimeInterval, "signInterval");
			if (hasTradeType) {

				StringBuilder onAddTimeIntervalSQL = new StringBuilder();

				if (query != null) {
					X.use(query.getAddTimeInterval(), ti -> {
						Date begin = ti.getFinalBegin();
						if (begin != null) {
							onAddTimeIntervalSQL.append(" AND uiLog.report_time >= #{input.addTimeInterval.finalBegin}");
						}
						Date end = ti.getFinalEnd();
						if (end != null) {
							onAddTimeIntervalSQL.append(" AND uiLog.report_time <= #{input.addTimeInterval.finalEnd}");
						}
					});
				}
				sql.LEFT_OUTER_JOIN("tr_user_income_daily_log uiLog ON uiLog.user_id = u.id AND  uiLog.agent_id = u.agent_id " + onAddTimeIntervalSQL);

				sql.GROUP_BY("e.agent_id");
			}
			sql.GROUP_BY("at.id");
			sql.ORDER_BY(hasTradeType ? "SUM(uiLog.total_integral) desc, at.id desc, at.status desc" : "at.id desc, at.status desc ");
			return sql.toString();
		}
	}

}
